/**
 * 云静导入
 */
layui.use(['jquery', 'yunj', 'upload', 'element', 'table', "validate"], function () {
    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let upload = layui.upload;
    let element = layui.element;
    let table = layui.table;
    let validate = layui.validate;

    class YunjImport {

        constructor(obj) {

            this.id = obj.id;                         // 当前对象id

            this.raw_el = obj.elem;                   // 原始元素

            this.raw_args = obj.args;                 // 原始数据

            this.sheets = obj.args.sheets;
            this.cols = obj.args.cols;
            this.limit = obj.args.limit;
            this.tips = obj.args.tips;

            this.raw_table = null;                    // 来源表格

            this.box_el = null;                       // 顶级容器
            this.btn_box_el = null;                   // 按钮容器
            this.step_box_el = null;                  // 步骤容器
            this.content_box_el = null;               // 内容容器

            this.templet_download_btn = null;
            this.templet_desc_sheet_title = "导入数据描述";
            this.templet_desc_sheet = null;         // 模板描述工作表
            this.templet_blob = null;

            this.file_upload_box = null;
            this.file = null;
            this.file_data = null;
            this.file_data_id = 1;
            this.file_data_table_id_prefix = "";
            this.file_data_table = null;

            this.import_data = null;
            this.import_data_sheet_validate_args = null;    // 导入sheet数据的验证参数{rule:{...},data_title:{...}}
            this.import_data_mark = null;                     // 导入数据的标识
            this.import_data_table_id_prefix = "";
            this.import_data_table = null;
            this.import_data_count = 0;
            this.import_data_total_count = 0;
            this.import_data_success_count = 0;
            this.import_data_fail_count = 0;

            this.step = 'one';

            this.init();

        }

        init() {
            let that = this;
            that.init_layout();
            that.set_data();
            that.file_upload_init();
            that.step_render();
            that.set_event_bind();
        }

        init_layout() {
            let that = this;
            let extraClass = that.raw_el.attr('class');
            extraClass = yunj.isUndefined(extraClass) ? '' : extraClass;
            let headerFixed = $('import[type=yunj]').length === 1 && extraClass.indexOf('header-fixed') !== -1;

            let tipsHtml = "";
            that.tips.forEach((v, i) => tipsHtml += `<li>${i + 1}、${v}</li>`);

            let layout = `<div class="layui-card yunj-import-box ${headerFixed ? 'header-fixed' : ''}" id="yunj_import_${that.id}">
                            <div class="layui-card-body yunj-import-header">
                                <div class="yunj-import-btn-box">
                                    <button type="button" class="layui-btn layui-btn-sm layui-btn-primary btn-import-prev">上一步</button>
                                    <button type="button" class="layui-btn layui-btn-sm btn-import-next">下一步</button>
                                    <button type="button" class="layui-btn layui-btn-sm btn-import-finish">完成</button>
                                </div>
                                <div class="yunj-import-step-box">
                                    <div class="yunj-import-step step-curr">
                                        <div class="txt">第一步：上传文件</div>
                                        <div class="arrow"></div>
                                    </div>
                                    <div class="yunj-import-step">
                                        <div class="txt">第二步：勾选数据</div>
                                        <div class="arrow"></div>
                                    </div>
                                    <div class="yunj-import-step">
                                        <div class="txt">第三步：导入数据</div>
                                        <div class="arrow"></div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-card-body yunj-import-content">
                                <div class="yunj-import-step-content step-curr" data-step="one">
                                    <div class="yunj-import-step-content-row">
                                        <button class="layui-btn layui-btn-sm layui-btn-normal yunj-btn-templet-download" >
                                            <i class="layui-icon layui-icon-download-circle"></i>
                                            点击下载示例模板
                                        </button>
                                    </div>
                                    <div class="yunj-import-step-content-row">
                                        <div class="layui-upload-drag">
                                            <i class="layui-icon layui-icon-upload"></i>
                                            <p>点击上传，或将文件拖拽到此处</p>
                                            <p class="file-preview"></p>
                                        </div>
                                    </div>
                                    <div class="yunj-import-step-content-row tips-box">
                                        <span class="title">提示！请注意以下问题：</span>
                                        <ul class="list">${tipsHtml}</ul>
                                    </div>
                                </div>
                                <div class="yunj-import-step-content" data-step="two">
                                    <div class="yunj-import-step-content-row tips-box">
                                        <span class="title">注意！！！请勾选要上传的数据行</span>
                                    </div>
                                    <div class="layui-tab yunj-import-step-content-row sheet-table">
                                        <ul class="layui-tab-title"></ul>
                                        <div class="layui-tab-content"></div>
                                    </div>
                                </div>
                                <div class="yunj-import-step-content" data-step="three">
                                    <div class="yunj-import-step-content-row import-progress-box">
                                        <div class="import-progress layui-progress layui-progress-big" lay-filter="import_progress" lay-showPercent="true">
                                            <div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>
                                        </div>
                                        <div class="import-progress-desc">
                                            <span class="total">合计：<span class="count">0</span></span>
                                            &nbsp;&nbsp;-&nbsp;&nbsp;
                                            <span class="success">成功：<span class="count">0</span></span>
                                            &nbsp;&nbsp;-&nbsp;&nbsp;
                                            <span class="fail">失败：<span class="count">0</span></span>
                                        </div>
                                    </div>
                                    <div class="yunj-import-step-content-row import-sheet-table"></div>
                                </div>
                            </div>
                        </div>`;
            that.raw_el.after(layout);
        }

        set_data() {
            let that = this;
            that.set_raw_table();
            let boxEl = $(`#yunj_import_${that.id}`);
            that.box_el = boxEl;
            that.btn_box_el = boxEl.find(".yunj-import-btn-box");
            that.step_box_el = boxEl.find(".yunj-import-step-box");
            that.content_box_el = boxEl.find(".yunj-import-content");
            that.templet_download_btn = boxEl.find(".yunj-btn-templet-download");
            that.set_templet_desc_sheet();
            that.set_templet_download_blob();
            that.file_upload_box = boxEl.find('.layui-upload-drag');
            that.file_data_table_id_prefix = `yunj_import_${that.id}_file_data_table_`;
            that.import_data_table_id_prefix = `yunj_import_${that.id}_data_table_`;
        }

        // 设置来源表格
        set_raw_table() {
            let that = this;
            let rawPageWin = yunj.rawPageWin();
            if(rawPageWin===null) return;
            let rawTableId = yunj.urlParam("raw_table","");
            if(rawTableId.length<=0) return;
            that.raw_table = rawPageWin.yunj.table[rawTableId];
        }

        set_templet_desc_sheet() {
            let that = this;
            let descSheet = {
                sheet: {},
                range: {s: {c: 0, r: 0}, e: {c: 0, r: 0}},
                merges: [
                    {s: {c: 0, r: 0}, e: {c: 1, r: 0}},
                    {s: {c: 0, r: 1}, e: {c: 1, r: 1}},
                ],
                cols: [{'wch': 10}, {'wch': 100}],
                row_idx: 2
            };
            let A1Cell = {
                v: "注意：黄色底纹列为必填项",
                s: {
                    font: {
                        name: "宋体",
                        sz: 9,
                        color: {rgb: "FFFF0000"}
                    },
                    alignment: {
                        vertical: "center"
                    }
                }
            };
            let A1CellRef = XLSX.utils.encode_cell({c: 0, r: 0});
            descSheet.sheet[A1CellRef] = A1Cell;
            that.templet_desc_sheet = descSheet;
            return that;
        }

        set_templet_desc_sheet_cell(args = {}) {
            let that = this;
            args = yunj.objSupp(args, {
                cell: null,
                is_merge: false,
                row_idx_inc: true,
                col_num: 0
            });
            let rowIdx = that.templet_desc_sheet.row_idx;
            let cellRef = XLSX.utils.encode_cell({c: args.col_num, r: rowIdx});
            that.templet_desc_sheet.sheet[cellRef] = args.cell;
            if (args.is_merge) that.set_templet_desc_sheet_merges(false);
            if (args.row_idx_inc) that.templet_desc_sheet.row_idx++;
        }

        set_templet_desc_sheet_merges(row_idx_inc = true) {
            let that = this;
            let rowIdx = that.templet_desc_sheet.row_idx;
            that.templet_desc_sheet.merges.push({s: {c: 0, r: rowIdx}, e: {c: 1, r: rowIdx}});
            if (row_idx_inc) that.templet_desc_sheet.row_idx++;
        }

        set_templet_desc_sheet_cols0_wch(wch) {
            let that = this;
            let cols0Wch = that.templet_desc_sheet.cols[0]["wch"];
            if (wch > cols0Wch) cols0Wch = wch;
            that.templet_desc_sheet.cols[0]["wch"] = cols0Wch;
        }

        templet_workbook_push_desc_sheet(workbook) {
            let that = this;
            let descSheet = that.templet_desc_sheet;
            descSheet.range.e.c = 1;
            descSheet.range.e.r = descSheet.row_idx;
            descSheet.sheet['!ref'] = XLSX.utils.encode_range(descSheet.range);
            descSheet.sheet['!cols'] = descSheet.cols;
            descSheet.sheet["!merges"] = descSheet.merges;
            workbook.SheetNames.push(that.templet_desc_sheet_title);
            workbook.Sheets[that.templet_desc_sheet_title] = descSheet.sheet;
        }

        // 设置模板blob
        set_templet_download_blob() {
            let that = this;
            // workbook
            let workbook = {
                SheetNames: [],
                Sheets: {},
            };

            // sheets
            that.sheets.forEach(sheet => {
                if (!that.cols.hasOwnProperty(sheet)) return;

                // desc
                that.set_templet_desc_sheet_cell({
                    cell: {
                        v: `${sheet}工作表字段描述如下：`,
                        s: {
                            font: {
                                name: "宋体",
                                sz: 9
                            },
                            alignment: {
                                vertical: "center"
                            }
                        }
                    },
                    is_merge: true
                });

                // workSheet
                let range = {s: {c: 0, r: 0}, e: {c: 0, r: 0}};
                let sheetCols = that.cols[sheet];
                let workSheet = {};
                let sheetColsWidth = [];
                let i = 0;
                for (let k in sheetCols) {
                    if (!sheetCols.hasOwnProperty(k)) continue;
                    let sheetCol = sheetCols[k];
                    let title = sheetCol["title"];
                    let defaultVal = sheetCol["default"];
                    let verify = sheetCol["verify"].length > 0 ? sheetCol["verify"].split("|") : [];
                    let desc = sheetCol["desc"];
                    let titleWch = yunj.xlsx_sheet_cell_wch(title);
                    let defaultWch = yunj.xlsx_sheet_cell_wch(defaultVal);

                    // desc
                    if (desc.length > 0) {
                        that.set_templet_desc_sheet_cell({
                            cell: {
                                v: title,
                                s: {font: {name: "宋体", sz: 9}, alignment: {vertical: "center", horizontal: "center"}}
                            },
                            row_idx_inc: false
                        });
                        that.set_templet_desc_sheet_cell({
                            cell: {
                                v: desc,
                                s: {font: {name: "宋体", sz: 9}, alignment: {vertical: "center", wrapText: true}}
                            },
                            col_num: 1
                        });
                        that.set_templet_desc_sheet_cols0_wch(titleWch);
                    }

                    // title
                    let titleCell = {
                        v: title,
                        t: "s",
                        s: {
                            fill: {
                                fgColor: {
                                    rgb: verify.indexOf("require") !== -1 ? "FFFFFF00" : "FFC0C0C0"
                                }
                            },
                            font: {
                                name: "宋体",
                                sz: 11
                            },
                            alignment: {
                                vertical: "center",
                                horizontal: "center",
                            },
                            border: {
                                right: {style: "thin"},
                                bottom: {style: "thin"},
                            }
                        }
                    };
                    let titleCellRef = XLSX.utils.encode_cell({c: i, r: 0});

                    // default
                    let defaultCell = {
                        v: defaultVal,
                        t: yunj.isNumber(defaultVal) ? "n" : (yunj.isBool(defaultVal) ? "b" : "s"),
                        s: {
                            font: {
                                name: "宋体",
                                sz: 11
                            },
                            alignment: {
                                vertical: "center",
                            }
                        }
                    };
                    let defaultCellRef = XLSX.utils.encode_cell({c: i, r: 1});

                    // wch
                    let wch = titleWch > defaultWch ? titleWch : defaultWch;
                    wch = wch > 10 ? wch : 10;
                    sheetColsWidth.push({'wch': wch});

                    workSheet[titleCellRef] = titleCell;
                    workSheet[defaultCellRef] = defaultCell;
                    i++;
                }

                // desc
                that.set_templet_desc_sheet_merges();

                range.e.c = i;
                range.e.r = 1;
                workSheet['!ref'] = XLSX.utils.encode_range(range);
                workSheet['!cols'] = sheetColsWidth;
                workbook.SheetNames.push(sheet);
                workbook.Sheets[sheet] = workSheet;
            });

            // desc
            that.templet_workbook_push_desc_sheet(workbook);

            // excel的配置项
            let wopts = {
                bookType: 'xlsx',   // 要生成的文件类型
                bookSST: false,    // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
                type: 'binary'
            };
            let wbout = XlsxStyle.write(workbook, wopts);
            // blob
            that.templet_blob = new Blob([yunj.str_to_array_buffer(wbout)], {type: "application/octet-stream"});
        }

        // 模板下载
        templet_download() {
            let that = this;
            if (yunj.isMobile()) {
                yunj.msg("抱歉！移动端暂不支持模板下载");
                return;
            }
            yunj.download({name: `${that.id}模板.xlsx`, blob: that.templet_blob});
        }

        // 文件上传初始化
        file_upload_init() {
            let that = this;
            upload.render({
                elem: `#yunj_import_${that.id} .layui-upload-drag`,
                accept: 'file',
                auto: false,
                choose: function (obj) {
                    //将每次选择的文件追加到文件队列
                    obj.pushFile();
                    //预读本地文件，如果是多文件，则会遍历。
                    obj.preview(function (index, file, result) {
                        // 判断文件格式
                        if (!yunj.isCsv(file) && !yunj.isXlsx(file) && !yunj.isXls(file)) {
                            yunj.msg('上传文件格式需为：xlsx/xls/csv');
                            that.file_upload_box.find('.file-preview').html('');
                            return false;
                        }
                        that.file_upload_box.find('.file-preview').html(file.name);
                        that.file = file;
                    });
                }
            });
        }

        // 事件绑定
        set_event_bind() {
            let that = this;

            that.templet_download_btn.on("click", function () {
                that.templet_download();
            });

            that.btn_box_el.on('click', '.btn-import-finish', function () {
                yunj.closeCurr();
            });

            that.btn_box_el.on('click', '.btn-import-next', function () {
                switch (that.step) {
                    case 'one':
                        if (!that.file) {
                            yunj.msg('请选择上传文件');
                            return false;
                        }
                        that.read_file_data(function () {
                            that.step = 'two';
                            that.step_render();
                        });
                        break;
                    case 'two':
                        that.set_import_data(function () {
                            that.step = 'three';
                            that.step_render();
                        });
                        break;
                    default:
                        return false;
                }
            });

            that.btn_box_el.on('click', '.btn-import-prev', function () {
                switch (that.step) {
                    case 'two':
                        that.step = 'one';
                        break;
                    case 'three':
                        that.step = 'two';
                        break;
                    default:
                        return false;
                }
                that.step_render();
            });

        }

        // 步骤宣染
        step_render() {
            let that = this;
            that.step_box_el.find('.yunj-import-step').removeClass('step-mark');
            that.step_box_el.find('.yunj-import-step').removeClass('step-curr');
            that.content_box_el.find('.yunj-import-step-content').removeClass('step-curr');
            that.btn_box_el.find('.layui-btn').removeClass('step-curr');
            switch (that.step) {
                case 'one':
                    that.step_box_el.find('.yunj-import-step').eq(0).addClass('step-curr');
                    that.btn_box_el.find('.btn-import-next').addClass('step-curr');
                    break;
                case 'two':
                    that.step_box_el.find('.yunj-import-step').eq(0).addClass('step-mark');
                    that.step_box_el.find('.yunj-import-step').eq(1).addClass('step-curr');
                    that.btn_box_el.find('.btn-import-prev').addClass('step-curr');
                    that.btn_box_el.find('.btn-import-next').addClass('step-curr');
                    break;
                case 'three':
                    that.step_box_el.find('.yunj-import-step').eq(0).addClass('step-mark');
                    that.step_box_el.find('.yunj-import-step').eq(1).addClass('step-mark');
                    that.step_box_el.find('.yunj-import-step').eq(2).addClass('step-curr');
                    that.btn_box_el.find('.btn-import-prev').addClass('step-curr');
                    that.btn_box_el.find('.btn-import-finish').addClass('step-curr');
                    break;
            }
            let stepContentBoxEl = that.content_box_el.find(`.yunj-import-step-content[data-step=${that.step}]`);
            that[`step_${that.step}_render`](stepContentBoxEl);
            stepContentBoxEl.addClass('step-curr');
        }

        // 步骤一渲染
        step_one_render(content_box_el) {
        }

        // 步骤二渲染
        step_two_render(content_box_el) {
            let that = this;
            // 创建表格
            content_box_el.find('.sheet-table .layui-tab-title').html('');
            content_box_el.find('.sheet-table .layui-tab-content').html('');
            let file_data = that.file_data;
            that.file_data_table = {};
            let i = 0;
            for (let sheet in file_data) {
                if (!file_data.hasOwnProperty(sheet)) continue;
                content_box_el.find('.sheet-table .layui-tab-title').append(`<li class="${i === 0 ? 'layui-this' : ''}">${sheet}</li>`);
                content_box_el.find('.sheet-table .layui-tab-content').append(`<div class="layui-tab-item ${i === 0 ? 'layui-show' : ''}">
                                                                                <table class="layui-table" id="${that.file_data_table_id_prefix + sheet}" lay-filter="${that.file_data_table_id_prefix + sheet}"></table>
                                                                            </div>`);
                that.step_two_table_render(sheet, file_data[sheet]);
                i++;
            }
        }

        // 步骤二表格渲染
        step_two_table_render(sheet, items) {
            let that = this;
            let sheetCols = that.cols[sheet];
            let cols = [{field: 'id', type: 'checkbox'}];
            for (let field in sheetCols) {
                if (!sheetCols.hasOwnProperty(field)) continue;
                cols.push({field: field, type: 'normal', title: sheetCols[field]["title"]});
            }
            let args = {
                elem: `#${that.file_data_table_id_prefix + sheet}`,
                url: '/admin/empty',
                method: 'post',
                contentType: 'application/json',
                parseData: function (res) {
                    return {
                        "code": 0,
                        "msg": 'success',
                        "count": 0,
                        "data": items
                    };
                },
                page: false,
                loading: true,
                text: {none: '暂无相关数据'},
                cols: [cols],
                done: function (res) {
                    table.resize(this.id);
                }
            };
            that.file_data_table[sheet] = table.render(args);
        }

        // 步骤三渲染
        step_three_render(content_box_el) {
            let that = this;
            // 创建表格
            content_box_el.find('.import-sheet-table').html('');
            let import_data = that.import_data;
            let sheetNum = Object.keys(import_data).length;
            that.import_data_table = {};
            let i = 1;
            for (let sheet in import_data) {
                if (!import_data.hasOwnProperty(sheet)) continue;
                let tableHtml = `<div class="layui-tab">
                                    <ul class="layui-tab-title">
                                        <li class="layui-this">${sheet}</li>
                                    </ul>
                                    <div class="layui-tab-content">
                                        <div class="layui-tab-item layui-show">
                                            <table class="layui-table" id="${that.import_data_table_id_prefix + sheet}" lay-filter="${that.import_data_table_id_prefix + sheet}"></table>
                                        </div>
                                    </div>
                                </div>`;
                content_box_el.find('.import-sheet-table').append(tableHtml);
                that.step_three_table_render(sheet, import_data[sheet], i === sheetNum);
                i++;
            }
        }

        /**
         * 步骤三表格渲染
         * @param sheet
         * @param items
         * @param start [是否执行上传]
         */
        step_three_table_render(sheet, items, start = false) {
            let that = this;
            let sheetCols = that.cols[sheet];
            let templetHtml = `<div>
                                <span class="import-row import-row-${sheet}-{{ d.id }} layui-badge layui-bg-gray">等待上传</span>
                              </div>`;
            let cols = [{
                field: 'id',
                type: 'normal',
                title: '状态',
                fixed: 'left',
                align: 'center',
                templet: templetHtml
            }];
            for (let field in sheetCols) {
                if (!sheetCols.hasOwnProperty(field)) continue;
                cols.push({field: field, type: 'normal', title: sheetCols[field]["title"]});
            }
            let args = {
                elem: `#${that.import_data_table_id_prefix + sheet}`,
                url: '/admin/empty',
                method: 'post',
                contentType: 'application/json',
                parseData: function (res) {
                    return {
                        "code": 0,
                        "msg": 'success',
                        "count": 0,
                        "data": items
                    };
                },
                page: false,
                loading: true,
                text: {none: '暂无相关数据'},
                cols: [cols],
                done: function (res) {
                    table.resize(this.id);
                    if (start) {
                        element.progress('import_progress', '0%');
                        that.step_three_import_count_render();
                        that.exec_import();
                    }
                }
            };
            that.import_data_table[sheet] = table.render(args);
        }

        // 验证导入数据行
        step_three_import_verify_rows(rows) {
            let that = this;
            let validateArgs = that.import_data_sheet_validate_args;
            let failRows = [];
            let passRows = [];
            for (let i = 0, l = rows.length; i < l; i++) {
                let rowData = rows[i];
                let sheet = rowData.sheet;
                if (!validateArgs.hasOwnProperty(sheet)) continue;
                validate.create({
                    rule: validateArgs[sheet]["rule"]
                });
                let res = validate.check(rowData.row, validateArgs[sheet]["data_title"]);
                if (!res) {
                    rowData.response_error = validate.getError();
                    failRows.push(rowData);
                    continue;
                }
                passRows.push(rowData);
            }
            return {pass_rows: passRows, fail_rows: failRows};
        }

        // 上传数据行状态渲染
        step_three_import_status_render(rows) {
            let that = this;
            for (let i = 0, l = rows.length; i < l; i++) {
                let row = rows[i];
                let rowEl = that.import_table_row_el(row.sheet, row.id);
                rowEl.removeClass('layui-bg-gray');
                if (row.hasOwnProperty("response_error")) {
                    that.import_data_fail_count++;
                    rowEl.html(row.response_error);
                } else {
                    that.import_data_success_count++;
                    rowEl.addClass('layui-bg-green');
                    rowEl.html('上传成功');
                }
            }
        }

        // 上传数量渲染
        step_three_import_count_render() {
            let that = this;
            let countBoxEl = that.content_box_el.find(`.yunj-import-step-content[data-step=${that.step}] .import-progress-desc`);
            countBoxEl.find('.total .count').html(that.import_data_total_count);
            countBoxEl.find('.success .count').html(that.import_data_success_count);
            countBoxEl.find('.fail .count').html(that.import_data_fail_count);
        }

        /**
         * 执行导入
         * @param num   [批次]
         */
        exec_import(num) {
            let that = this;

            num = num || 1;
            let l = that.limit;
            let startIndex = (num - 1) * l;
            let maxIndex = that.import_data_mark.length - 1;
            let rows = [];
            for (let i = 0; i < l; i++) {
                let index = startIndex + i;
                if (index > maxIndex) break;
                let mark = that.import_data_mark[index];
                that.import_table_row_el(mark.sheet, mark.id).html('正在上传');
                rows.push(mark);
            }
            let {pass_rows, fail_rows} = that.step_three_import_verify_rows(rows);
            let requestData = {builder_id: that.id, builder_async_type: "import", rows: pass_rows};
            yunj.request({
                url: yunj.url(true),
                data: requestData,
                eventTitle: '数据导入',
                loading: {enable: false},
                successCallback: function (requestArgs, responseRes) {
                    let data = responseRes.data;
                    let rows = [...data.rows, ...fail_rows];
                    that.import_data_count += rows.length;
                    // 进度
                    let rate = Math.floor((that.import_data_count / that.import_data_total_count) * 100);
                    rate = rate > 100 ? 100 : rate;
                    element.progress('import_progress', `${rate}%`);
                    // 更改数据行状态
                    that.step_three_import_status_render(rows);
                    // 上传数量渲染
                    that.step_three_import_count_render();
                    if (rate < 100) that.exec_import(num + 1);
                    yunj.msg('数据导入完成');
                    that.raw_table && that.raw_table.render();
                },
            });

        }

        // 导入表格行元素获取
        import_table_row_el(row_sheet, row_id) {
            let that = this;
            return that.content_box_el.find(`.import-row-${row_sheet}-${row_id}`);
        }

        // 读取文件数据
        read_file_data(callback) {
            let that = this;
            let reader = new FileReader();
            reader.onload = function (e) {
                let data = e.target.result;
                let workbook = XLSX.read(data, {type: 'binary'});
                that.file_data = [];
                that.file_data_id = 1;
                workbook.SheetNames.forEach(sheet => {
                    if (sheet === that.templet_desc_sheet_title) return;
                    let sheetRows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
                    let items = that.file_data_handle(sheet, sheetRows);
                    if (yunj.isString(items)) {
                        yunj.msg(items);
                        throw new Error(items);
                    }
                    that.file_data[sheet] = items;
                });
                callback && callback();
            };
            reader.readAsBinaryString(that.file);
        }

        // 原始文件数据处理
        file_data_handle(sheet, sheet_rows) {
            let that = this;
            let sheetCols = that.cols[sheet];
            let items = [];
            for (let i = 0, l = sheet_rows.length; i < l; i++) {
                let row = sheet_rows[i];
                let item = {id: that.file_data_id++, raw_data: row};
                for (let k in sheetCols) {
                    if (!sheetCols.hasOwnProperty(k)) continue;
                    let title = sheetCols[k]["title"];
                    if (!row.hasOwnProperty(title)) return '上传文件数据格式错误，详见示例模板';
                    item[k] = row[title];
                }
                items.push(item);
            }
            return items;
        }

        // 设置导入数据
        set_import_data(callback) {
            let that = this;
            that.import_data = {};
            that.import_data_sheet_validate_args = {};
            that.import_data_mark = [];
            that.import_data_count = 0;
            that.import_data_total_count = 0;
            that.import_data_success_count = 0;
            that.import_data_fail_count = 0;
            // 获取选中数据
            for (let sheet in that.file_data) {
                if (!that.file_data.hasOwnProperty(sheet)) continue;
                let checkedData = table.checkStatus(that.file_data_table_id_prefix + sheet);
                let dataCount = checkedData.data.length;
                if (dataCount <= 0) continue;
                that.import_data[sheet] = checkedData.data;
                that.import_data_total_count += dataCount;
                let validateArgs = {rule: {}, data_title: {}};
                let cols = that.cols[sheet];
                for (let k in cols) {
                    if (!cols.hasOwnProperty(k)) continue;
                    let col = cols[k];
                    if (col.verify.length <= 0) continue;
                    validateArgs.rule[k] = col.verify;
                    validateArgs.data_title[k] = col.title;
                }
                that.import_data_sheet_validate_args[sheet] = validateArgs;
                for (let i = 0; i < dataCount; i++) {
                    let data = checkedData.data[i];
                    let {LAY_TABLE_INDEX, id, raw_data, ...row} = data;
                    that.import_data_mark.push({sheet: sheet, id: data.id, row: row});
                }
            }
            if (yunj.isEmptyObj(that.import_data)) {
                yunj.msg('请选择需要上传的数据行');
                return false;
            }
            callback && callback();
        }

    }

    $(doc).ready(function () {
        win.yunj.import = {};

        let importEls = $('import[type=yunj]');
        if (yunj.isEmptyObj(YUNJ_IMPORT) || importEls.length <= 0) return false;

        yunj.include_css(`/static/yunj/css/import.min.css?v=${YUNJ_VERSION}`).then(() => {
            yunj.include_xlsx_style().then(() => {
                importEls.each(function () {
                    let id = $(this).attr('id');
                    if (!YUNJ_IMPORT.hasOwnProperty(id)) return true;
                    let args = YUNJ_IMPORT[id];
                    win.yunj.import[id] = new YunjImport({
                        id: id,
                        elem: $(this),
                        args: args
                    });
                });
            });
        });

    });

});